#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
import json
import sys
import base64
import time
from rest_framework import status

IS_PY3 = sys.version_info.major == 3

if IS_PY3:
    from urllib.request import urlopen
    from urllib.request import Request
    from urllib.error import URLError
    from urllib.parse import urlencode
    timer = time.perf_counter
else:
    from urllib2 import urlopen
    from urllib2 import Request
    from urllib2 import URLError
    from urllib import urlencode
    if sys.platform == "win32":
        timer = time.clock
    else:
        # On most other platforms the best timer is time.time()
        timer = time.time

import ssl
ssl._create_default_https_context = ssl._create_unverified_context

#填写百度控制台中相关开通了“语音合成”接口的应用的的API_KEY及SECRET_KEY
API_KEY = 'Hu5ZUYeS1dlvdtGRFG0Rkibh'   
SECRET_KEY = 'hfQR5ReuBRYG93cpzhpXatT2YCDk8kSX'


"""  获取请求TOKEN start 通过开通语音合成接口的百度应用的API_KEY及SECRET_KEY获取请求token"""

class DemoError(Exception):
    pass

TOKEN_URL = 'https://openapi.baidu.com/oauth/2.0/token'
SCOPE = 'audio_tts_post'  # 有此scope表示有tts能力，没有请在网页里勾选

def fetch_token():
    params = {'grant_type': 'client_credentials',
              'client_id': API_KEY,
              'client_secret': SECRET_KEY}
    post_data = urlencode(params)
    if (IS_PY3):
        post_data = post_data.encode( 'utf-8')
    req = Request(TOKEN_URL, post_data)
    try:
        f = urlopen(req)
        result_str = f.read()
    except URLError as err:
        print('token http response http code : ' + str(err.code))
        result_str = err.read()
    if (IS_PY3):
        result_str =  result_str.decode()

#    print(result_str)
    result = json.loads(result_str)
#    print(result)
    if ('access_token' in result.keys() and 'scope' in result.keys()):
        if not SCOPE in result['scope'].split(' '):
            raise DemoError('scope is not correct')
#        print('SUCCESS WITH TOKEN: %s ; EXPIRES IN SECONDS: %s' % (result['access_token'], result['expires_in']))
        return result['access_token']
    else:
        raise DemoError('MAYBE API_KEY or SECRET_KEY not correct: access_token or scope not found in token response')

"""  获取鉴权结束，TOKEN end """

"""  发送语音合成请求 """
def sendTTSRequest(text):
    #待进行合成的文本，需要为UTF-8编码；输入多段文本时，文本间会插入1s长度的空白间隔
    url = 'https://aip.baidubce.com/rpc/2.0/tts/v1/create'  #创建长文本语音合成任务请求地址

    body = {
        "text": text,
        "format": "mp3-16k",        #音频格式，支持"mp3-16k","mp3-48k", "wav", "pcm-8k","pcm-16k"
        "voice": 0,        #音库，度小宇=1，度小美=0，度逍遥（基础）=3，度丫丫=4；度逍遥（精品）=5003，度小鹿=5118，度博文=106，度小童=110，度小萌=111，度米朵=103，度小娇=5
        "lang": "zh"       #语言选择,目前只有中英文混合模式，填写固定值"zh"
    }

    # token = {"access_token":"24.19fd456ac888cb1d1cdef56fcb1b567a.2592000.1579157900.282828-11778899"}

    token = {"access_token":fetch_token()}

    headers = {'content-type': "application/json"}

    response = requests.post(url,params=token,data = json.dumps(body), headers = headers)

    # 返回请求结果信息，获得task_id，通过长文本语音合成查询接口，获取合成结果
    print(response.text)
    return response.status_code, json.loads(response.text)


def getTTSResult(task_id_list):
    #长文本合成任务id列表，支持同时查询多个，task_id是通过创建长文本合成任务时获取到的每个合成任务对应的值
    url = 'https://aip.baidubce.com/rpc/2.0/tts/v1/query'  #查询长文本语音合成任务结果请求地址
    body = {
        "task_ids": task_id_list
    }

    token = {"access_token":fetch_token()}

    headers = {'content-type': "application/json"}

    response = requests.post(url,params=token,data = json.dumps(body), headers = headers)
    print(json.dumps(response.json(), ensure_ascii=False))
    return response.status_code, response.json()

def baidu_tts(text):
    sts, data =  sendTTSRequest([text])
    if not status.is_success(sts):
        return None
    if 'task_id' not in data:
        return None
    task_id = data['task_id']

    sts, data = getTTSResult([task_id])
    MAX_TIMEOUT = 100
    tt = 0
    while tt < MAX_TIMEOUT:
        task_status = data["tasks_info"][0]['task_status']
        if task_status == 'Failure':
            return None
        elif task_status == 'Success':
            task_result = data["tasks_info"][0]['task_result']
            return task_result['speech_url']      

        tt += 1
        time.sleep(5)
        sts, data = getTTSResult([task_id])



